#pragma once
#include"Socket.hpp"
#include"Cal_Server.hpp"
#include"log.hpp"
#include<iostream>
#include<functional>
#include"Daemon.hpp"
using func_t = function<string(std::string&)>;
class TcpServer{
public:
    TcpServer(uint16_t port,func_t callback) 
        :_port(port)
        ,_callback(callback)
    {

    }
    ~TcpServer() 
    {

    }
    bool InitServer()
    {
        _Listensocket.CreateSocket();
        _Listensocket.Bind(_port);
        _Listensocket.Listen();
        l(Info,"init server success");
        return true;
    }
    void Start()
    {
        
        // signal(SIGCHLD,SIG_IGN);
        // signal(SIGPIPE,SIG_IGN);
        while(true)
        {
            std::string ip;
            uint16_t port;
            int socketfd = _Listensocket.Accept(&ip,&port);
            string req;
            l(Info,"accept a new link");
            if(socketfd < 0) continue;
            if(fork() == 0) 
            {
                _Listensocket.Close();
                //服务
                while(true)
                {
                    char buff[128];
                    ssize_t n = read(socketfd,buff,sizeof(buff));
                    if(n > 0)
                    {
                        buff[n] = 0;
                        req += buff;
                        l(Debug,"%s",req.c_str());

                        //可能一次收到多个任务,一次一次解析,因为Decode逻辑中删除了一部分
                        while(true)
                        {
                            string info = _callback(req);
                            if(info.empty()) break;
                            write(socketfd,info.c_str(),info.size());
                        }
                        
                    }
                    else if(n == 0) break;
                    else break;
                }
                exit(0);
            }
            close(socketfd);
        }
    }
private:
    uint16_t _port;
    Socket _Listensocket;
    func_t _callback;
};